AWS CDK で Event bus の DLQ を簡単に設定可能になりました

AWS CDK で Event bus の DLQ を簡単に設定可能になりました

Clock Icon2024.10.25

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最近のリリースである v2.163.0 で、下記のアップデートが追加されていました。

events: dead letter queue for an Event Bus (#30628) (318eae6), closes #30531

Amazon EventBridge では、Event bus に関連付けた Rule により、データソースから受信したイベントをターゲットにルーティングさせることができます。


Event buses in Amazon EventBridge - Amazon EventBridge から引用

そして、Event bus ではイベントの処理に失敗したイベントをキャプチャするための DLQ (Dead Letter Queue) を設定することができます。これは Rule のターゲットに対して設定するものとは別物となっており、下記図では①の部分に該当します。


Using dead-letter queues to capture encrypted event errors in EventBridge - Amazon EventBridge から引用

そして今回の AWS CDK のアップデートにより、この Event bus の DLQ を L2 Construct により簡単に設定可能になりました。

試してみた

CDK パッケージのアップデート

AWS CDK モジュールを v2.163.0 以上にアップデートします。

npm i aws-cdk-lib@latest aws-cdk@latest

CDK 実装

カスタムの Event bus に DLQ を設定する CDK コードです。EventBus クラスで deadLetterQueue プロパティを指定することで DLQ を設定できます。

lib/sample-app-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as events from 'aws-cdk-lib/aws-events';

export class SampleApp extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const dlq = new sqs.Queue(this, 'DLQ');

    const bus = new events.EventBus(this, 'Bus', {
      deadLetterQueue: dlq, // DLQ を設定
    });

    new events.Rule(this, 'Rule', {
      eventBus: bus,
      eventPattern: {
        source: ['my.custom.source'],
      },
    });
  }
}

CDK diff で差分を確認してみます。Event bus で DeadLetterConfig が追加されていることが確認できます。

$ npx cdk diff
start: Building 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
success: Built 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
start: Publishing 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
success: Published 96386930817c6798e83748f0fc7d6a7ddd3ffa58aee745d657107a8799c72906:current_account-current_region
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Stack SampleApp
Resources
[~] AWS::Events::EventBus Bus BusEA82B648
 └─ [+] DeadLetterConfig
     └─ {"Arn":{"Fn::GetAtt":["DLQ581697C4","Arn"]}}

✨  Number of stacks with differences: 1

上記をデプロイして、DLQ の設定を反映させます。

作成された Event bus です。ここで bus の DLQ の設定も確認したいところですが、残念ながらマネジメントコンソールからの確認方法は現在は提供されていないようです。

ちなみに Event rule にターゲットが設定されている場合はそちらに DLQ の設定がありますがこれは前述の図の②に該当するもので、別物となります。

Event bus の DLQ の動作確認

作成した Event bus に設定した DLQ の動作確認をしてみます。ここでは意図的にイベントを失敗させるために、bus に無効な KMS キーを設定します。

まず有効な KMS キーを bus に設定します。

lib/sample-app-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as events from 'aws-cdk-lib/aws-events';
import * as kms from 'aws-cdk-lib/aws-kms';

export class SampleApp extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const dlq = new sqs.Queue(this, 'DLQ');

    const kmsKey = new kms.Key(this, 'Key');

    const bus = new events.EventBus(this, 'Bus', {
      deadLetterQueue: dlq,
      kmsKey,
    });

    new events.Rule(this, 'Rule', {
      eventBus: bus,
      eventPattern: {
        source: ['my.custom.source'],
      },
    });
  }
}

作成した KMS キーを無効にします。

aws kms disable-key --key-id $KMS_KEY_ID

送信するイベントのファイルを作成します。

event.json
[
  {
    "Source": "my.custom.source",
    "DetailType": "myDetailType",
    "Detail": "{ \"key1\": \"value1\" }"
  }
]

AWS CLI でイベントを送信すると、KMS キーが無効であるため配信が失敗したようです。

$ aws events put-events --entries file://event.json
{
    "FailedEntryCount": 1,
    "Entries": [
        {
            "ErrorCode": "KMSEncryptionException",
            "ErrorMessage": "arn:aws:kms:ap-northeast-1:XXXXXXXXXXXX:key/fc772eec-30c8-4c1c-ad80-7668e5b81308 is disabled."
        }
    ]
}

イベント送信後に bus に設定した DLQ の SQS キューからイベントの受信を試みてみましたが、取得はできませんでした。

$ aws sqs receive-message --queue-url $DLQ_URL

マネジメントコンソールから確認できる Event bus のメトリクスでも、他の配信のメトリクスは記録されていますが、「Invocation sent to DLQ」については記録が行われていません。

KMS キーが無効であることにより配信失敗したイベントは、DLQ には送信されないようです。実際に DLQ が動作するのは Event bus 自体で障害が発生しているなどの場合でしょうか。

おわりに

AWS CDK で Event bus の DLQ を簡単に設定可能になりました。

Event bus は既定では Default の bus が使われますが、今回の検証のようにカスタムの bus を使用する場合には DLQ を設定しておくことで、イベントの配信失敗時に対処することが可能となります。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.